package com.gframework.mybatis.dao;

import java.io.Serializable;
import java.util.Collection;

import org.apache.ibatis.annotations.DeleteProvider;
import org.apache.ibatis.annotations.InsertProvider;
import org.apache.ibatis.annotations.Lang;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.UpdateProvider;

import com.gframework.mybatis.dao.mybatis.plugins.DeleteHelper;
import com.gframework.mybatis.dao.mybatis.provider.core.ProviderPlusLanguageDriver;
import com.gframework.mybatis.dao.mybatis.provider.per.TableBasicDaoProvider;
import com.gframework.sqlparam.BeanSqlParam;
import com.gframework.sqlparam.SqlParam;

/**
 * 基本表dao操作接口.
 * 此接口定义了表相关的操作方法（无主键操作）
 * 
 * @since 1.0.0
 * @author Ghwolf
 * @param <T> 表对应实体类的类型 {@link Serializable}接口子类，必须是一个POJO类型.
 * @see SqlParam
 * @see BeanSqlParam
 * 
 * @see IPrimaryDAO
 * @see IViewDao
 */
public interface ITableBasicDAO<T extends Serializable> extends IViewDao<T> {

	/**
	 * 保存一条数据，只会保存非null属性内容(自动增长列除外).
	 * 
	 * @param vo 要保存的实体类对象，不能为null
	 * @return 返回更新的数据行数，成功返回1，否则返回0
	 */
	@InsertProvider(TableBasicDaoProvider.class)
	@Lang(ProviderPlusLanguageDriver.class)
	public int save(T vo);

	/**
	 * 保存一条数据，会保存所有属性内容(自动增长列除外).
	 * 
	 * @param vo 要保存的实体类对象，不能为null
	 * @return 返回更新的数据行数，成功返回1，否则返回0
	 */
	@InsertProvider(TableBasicDaoProvider.class)
	@Lang(ProviderPlusLanguageDriver.class)
	public int saveAllColumn(T vo);

	/**
	 * 批量添加数据，只会保存非null属性内容(自动增长列除外).
	 * 忽略集合中的null对象
	 * 
	 * @param vos 要保存的实体类对象集合，不能为null
	 * @return 返回更新的数据行数
	 */
	@InsertProvider(TableBasicDaoProvider.class)
	@Lang(ProviderPlusLanguageDriver.class)
	public int saveBatch(@Param("vos") Collection<T> vos);

	/**
	 * 批量添加数据，会保存所有属性内容(自动增长列除外).
	 * 
	 * @param vos 要保存的实体类对象集合，不能为null
	 * @return 返回更新的数据行数
	 */
	@InsertProvider(TableBasicDaoProvider.class)
	@Lang(ProviderPlusLanguageDriver.class)
	public int saveBatchAllColumn(@Param("vos") Collection<T> vos);

	/**
	 * 根据自定义条件更新(除主键之外的)非null属性字段.
	 * 
	 * @param param 自定义更新条件及更新数据封装对象，不能为null
	 * @return 返回更新的数据行数
	 */
	@UpdateProvider(TableBasicDaoProvider.class)
	@Lang(ProviderPlusLanguageDriver.class)
	public int update(BeanSqlParam<T> param);

	/**
	 * 根据自定义条件更新(除主键之外的)全部属性字段.
	 * 
	 * @param param 自定义更新条件及更新数据封装对象，不能为null
	 * @return 返回更新的数据行数
	 */
	@UpdateProvider(TableBasicDaoProvider.class)
	@Lang(ProviderPlusLanguageDriver.class)
	public int updateAllColumn(BeanSqlParam<T> param);

	/**
	 * 根据自定义条件删除（真实删除）数据.
	 * 如果你想实现逻辑删除，可以使用低耦合的逻辑删除插件{@link DeleteHelper}
	 * 
	 * @param param 自定义删除条件封装对象
	 * @return 返回删除的数据行数
	 * @see DeleteHelper DeleteHelper逻辑删除插件
	 */
	@DeleteProvider(TableBasicDaoProvider.class)
	@Lang(ProviderPlusLanguageDriver.class)
	public int delete(SqlParam param);

}
